package net.sea.commons.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 执行bat或shshell脚本
 * 
 * @author 华成伍
 *
 */
public class ShellUtils {
	/**
	 * 执行windows的批处理文件
	 * 
	 * @param batFile
	 *            批处理文件
	 */
	private static void callCmd(File batFile) {
		Process process = null;
		try {
			/*
			 * <p>
			 * java中如何调用CMD命令
			 * cmd /c dir 是执行完dir命令后关闭命令窗口。 
			 * cmd /k dir 是执行完dir命令后不关闭命令窗口。
			 * cmd /c start dir 会打开一个新窗口后执行dir指令，原窗口会关闭。 
			 * cmd /k start dir 会打开一个新窗口后执行dir指令，原窗口不会关闭
			 * </p>
			 */
			process = Runtime.getRuntime().exec(
					"cmd.exe /c " + batFile.getAbsolutePath());
			flushCache(process.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		done(process);
	}

	/**
	 * 执行单条命令或启动指定应用程序
	 * 
	 * @param cmd
	 *            单条命令或应用程序
	 */
	public static void callCmd(String cmd) {
		Process process = null;
		try {
			/*
			 * <p>
			 * java中如何调用CMD命令
			 * cmd /c dir 是执行完dir命令后关闭命令窗口。 
			 * cmd /k dir 是执行完dir命令后不关闭命令窗口。
			 * cmd /c start dir 会打开一个新窗口后执行dir指令，原窗口会关闭。 
			 * cmd /k start dir 会打开一个新窗口后执行dir指令，原窗口不会关闭
			 * </p>
			 */
			process = Runtime.getRuntime().exec("cmd.exe /c " + cmd);
			flushCache(process.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		done(process);
	}

	/**
	 * 进程执行完成后的方法
	 * 
	 * @param process
	 *            执行进程
	 */
	private static void done(Process process) {
		int ret = process.exitValue();
		if (ret == 0) {
			System.out.println("程序正常执行完毕!");
		} else {
			System.out.println("程序异常结束!");
		}
	}

	/**
	 * 执行linux的shell脚本
	 * 
	 * @param shellFile
	 *            shell脚本文件
	 */
	private static void callShell(File shellFile) {
		Process process = null;
		try {
			Runtime rt = Runtime.getRuntime();
			process = rt.exec(shellFile.getAbsolutePath());
			flushCache(process.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		done(process);
	}

	/**
	 * 刷新命令行缓存
	 * 
	 * @param in
	 *            输入流
	 */
	private static void flushCache(InputStream in) {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(in));
			String cacheStr = "";
			while ((cacheStr = br.readLine()) != null) {
				System.out.println(cacheStr);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					br = null;
				}
			}
		}
	}

	/**
	 * 执行批处理文件或者shell脚本
	 * 
	 * @param shellFile
	 *            批处理文件或者shell脚本
	 */
	public static void excuteShell(File shellFile) {
		String os = "windows";
		if ("windows".equalsIgnoreCase(os)) {
			callCmd(shellFile);
		} else if ("liunx".equalsIgnoreCase(os)) {
			callShell(shellFile);
		}
	}
}
